package com.hsyt.pfc.exception;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.helpers.MessageFormatter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @Description: code容器工具类，用于根据code和变量获取message
 * @ClassName: CodeContainer
 * @Package: com.hsyt.pfc.support.core
 * @Author: wangze@hsyuntai.com
 * @Date: 2018年8月8日 14:08
 */
public class CodeContainer implements ConfigurationListener, InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(CodeContainer.class);

    private static final String DEFAULT_MSG = "";

    private static final String DEFAULT_CODE_CONFIG_PATH = "classpath*:config/*_code.*";

    private static final Map<String, HashMap<String, String>> CODE_MAPPINGS = new HashMap();

    private static boolean inited = false;

    private static List<String> configKeys;

    private static Resource[] locations;

    @Override
    public void resourceChanged(String configKey, Resource configResource) {
        LOGGER.info("resourceChanged configKey:{}  value: {}", configKey, configResource.getFilename());
        loadCodeConfig(configResource);
    }

    @Override
    public void configChanged(String configKey, Properties propeties) {
        HashMap<String, String> map = new HashMap();
        Iterator iterator;

        iterator = propeties.keySet().iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            map.put((String) key, propeties.getProperty((String) key));
        }
        CODE_MAPPINGS.put(configKey,map);
    }

    @Override
    public List<String> getConfigKeys() {
        return configKeys;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        init();
    }

    private static void init() {
        if (null == locations) {
            locations = ResourceUtil.getResource(DEFAULT_CODE_CONFIG_PATH);
        }

        if (locations != null && locations.length > 0) {
            configKeys = new ArrayList();
        }

        Resource[] resources = locations;

        int resLength = resources.length;

        for (int i = 0; i < resLength; ++i) {
            Resource resource = resources[i];
            configKeys.add(resource.getFilename());
            loadCodeConfig(resource);
        }
        inited = true;
    }

    private static void loadCodeConfig(Resource resource) {
        String file = resource.getFilename();
        HashMap<String, String> codeMap = loadNewConfig(resource);
        CODE_MAPPINGS.put(file, codeMap);

        LOGGER.debug("cdoe properties config:{}", JSON.toJSONString(codeMap));
        LOGGER.info("load code properties file  > {} success !", file);
    }

    private static HashMap<String, String> loadNewConfig(Resource res) {
        HashMap<String, String> map = new HashMap();
        Iterator iterator;

        Properties prop = ResourceUtil.transToProperties(res);
        iterator = prop.keySet().iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            map.put((String) key, prop.getProperty((String) key));
        }

        return map;
    }

    public static String getCodeMessage(String code, Object... pattern) {
        try {
            if (!inited) {
                init();
            }

            String message = null;

            Iterator iterator = CODE_MAPPINGS.values().iterator();
            while (iterator.hasNext()) {
                Map<String, String> codeMap = (Map<String, String>) iterator.next();
                if (codeMap.containsKey(code)) {
                    message = codeMap.get(code);
                    break;
                }
            }
            if (!StringUtils.hasLength(message)) {
                LOGGER.warn("未找到code[{}]的定义!", code);
                if (pattern != null && pattern.length > 0) {
                    message = pattern.length > 1 ? Arrays.toString(pattern) : String.valueOf(pattern[0]);
                }
            }

            return MessageFormatter.arrayFormat(message, pattern).getMessage();
        } catch (Exception e){
            LOGGER.error(e.getMessage());
            return DEFAULT_MSG;
        }
    }

}
